<?php
/**
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace backend\controllers;

use builder\base\BaseController;
use builder\form\FormBuilder;
use builder\helper\App;
use builder\helper\H5;
use common\models\Admin;
use common\models\SystemGroup;
use common\models\SystemGroupService;
use extend\Extend;

/**
 * 管理员
 * @author cleverstone
 * @since ym2.0
 */
class AdminController extends BaseController
{
    public $actionVerbs = [
        'index' => ['GET'],
        'create' => ['GET', 'POST'],
        'update' => ['GET', 'POST'],
        'delete' => ['POST'],
        'detail' => ['GET'],
    ];

    /**
     * 列表
     * @return string
     * @throws \builder\base\InvalidInstanceException
     * @throws \builder\base\NotFoundParamsException
     */
    public function actionIndex()
    {
        $viewBuilder = $this->viewBuilder;

        $table = $viewBuilder->table->setId('admin_index');
        if ($this->isAjax) {
            $table->setQuery(function () {
                $params = $this->filteredGet;
                $startAt = null;
                $endAt = null;
                if (!empty($params['create_at'])) {
                    list($startAt, $endAt) = array_map('trim', explode('/', $params['create_at']));
                }

                $query = Admin::query();
                $query->andFilterWhere([
                    'and',
                    [
                        'or',
                        ['like', 'username', isset($params['keyword']) ? $params['keyword'] : null],
                        ['like', 'email', isset($params['keyword']) ? $params['keyword'] : null],
                        ['like', 'mobile', isset($params['keyword']) ? $params['keyword'] : null],
                    ],
                    ['status' => isset($params['status']) ? $params['status'] : null],
                    ['between', 'created_at', $startAt, $endAt],
                ]);

                return $query;
            })
                ->setColumnDependency(function ($rows) {
                    $groupColumns = SystemGroup::query(['name'])->indexBy('id')->column();
                    $groupColumns[Admin::ADMIN_GROUP] = '<i class="bi bi-people-fill f14 pr-1"></i>拥有者';

                    return $groupColumns;
                })
                ->setOrderBy(['id' => SORT_DESC])
                ->setColumns([
                    'id',
                    'photo' => function ($row) {
                        return $row['photo'] ? H5::imgX30($row['photo']) : '-';
                    },
                    'username',
                    'email' => function ($row) {
                        return $row['email'] ?: '-';
                    },
                    'mobile' => function ($row) {
                        return $row['mobile'] ?: '-';
                    },
                    'status' => function ($row) {
                        return H5::badge($row['status'] ? '正常' : '封停', $row['status'] ? 'primary' : 'red');
                    },
                    'deny_end_time' => function ($row) {
                        return $row['deny_end_time'] ?: '-';
                    },
                    'group' => function ($row, $dependency) {
                        return $dependency[$row['group']];
                    },
                    'created_at',
                    'updated_at',
                    // 操作项
                    'op_admin_delete' => function ($row) {
                        return $row['group'] != Admin::ADMIN_GROUP;
                    },
                ]);
        } else {
            $table->setTitle('管理员列表')
                ->setRootLayout([
                    'attribute' => [
                        'ym2-image-group' => '',
                    ],
                ])
                ->setTableHead([
                    $this->tableHead->field('id')->title('ID'),
                    $this->tableHead->field('photo')->title('头像'),
                    $this->tableHead->field('username')->title('账号'),
                    $this->tableHead->field('email')->title('邮箱'),
                    $this->tableHead->field('mobile')->title('手机号'),
                    $this->tableHead->field('status')->title('状态'),
                    $this->tableHead->field('deny_end_time')->title('封停截止'),
                    $this->tableHead->field('group')->title('管理组'),
                    $this->tableHead->field('created_at')->title('添加时间'),
                    $this->tableHead->field('updated_at')->title('更新时间'),
                    $this->tableHead->toolbar()->title('操作项')->minWidth(130)->maxWidth(210),
                ])
                ->setRowOperation([
                    $this->rowOperation->modal()->title('查看')->route('admin/detail')->height(610)->closeBtn(),
                    $this->rowOperation->modal()->title('编辑')->route('admin/update')->height(838),
                    $this->rowOperation->ajax()->title('删除')->route('admin/delete')->method('POST')->id('op_admin_delete'),
                ])
                ->setToolbarCustom([
                    $this->toolbarCustom->modal()->btnClass('btn-primary')->title('新增')->route('admin/create'),
                ])
                ->setToolbarFilter([
                    'keyword' => $this->toolbarFilter->text()->label('关键词')->placeholder('请输入账号/邮箱/手机号')->uiClass('w-330'),
                    'create_at' => $this->toolbarFilter->datetime()->label('注册时间')->placeholder('请选择')->uiClass('w-330 mx-md-3'),
                    'status' => $this->toolbarFilter->select()->label('状态')->placeholder('请选择')->options(['封停/锁定', '正常'])->uiConfig('minimumResultsForSearch', -1)->uiClass('w-330 mr-md-3'),
                ]);
        }

        return $viewBuilder->render();
    }

    /**
     * 新增
     * @return string
     * @throws \yii\base\Exception
     * @throws \yii\base\InvalidConfigException
     * @throws \Exception
     */
    public function actionCreate()
    {
        if ($this->isPost) {
            $bodyParams = $this->filteredPost;
            $bodyParams['photo'] = App::getFileLinkFromParams($bodyParams, 'photo');

            $user = new Admin();
            $user->setScenario('user_add');
            $user->load($bodyParams);
            $user->path = '-0-';
            if (!$user->validate()) {
                return $this->asFail($user->error);
            }

            $user->setPassword($user->password_hash);
            $user->invite_code = Admin::generateInviteCode();
            $user->google_key = Extend::googleAuth()->createSecret();
            $user->generateAuthKey();
            $user->sso_key = Admin::generateSSOKEY();
            $user->access_token = Admin::generateAccessToken();

            $user->save(false);
            return $this->asOk("新增管理员账号【{$user->username}】成功");
        } else {
            return FormBuilder::instance(['id' => 'admin_create'])
                ->setTitle('新增')
                ->setPartial()
                ->setRequiredStyle()
                ->setFormControl([
                    'photo' => $this->formControl->file()->label('头像')->max(1)->scenarioImage(),
                    'username' => $this->formControl->text()->label('账号')->required()->placeholder('请填写账号'),
                    'password_hash' => $this->formControl->password()->label('密码')->required()->placeholder('请填写密码'),
                    'password_hash_repeat' => $this->formControl->password()->label('确认密码')->required()->placeholder('请重复密码'),
                    'email' => $this->formControl->text()->label('邮箱')->placeholder('请填写邮箱'),
                    'mobile' => $this->formControl->number()->label('手机号')->placeholder('请填写手机号'),
                    'group' => $this->formControl->xselectTree()
                        ->label('管理组')
                        ->tips('请选择管理组')
                        ->radio()
                        ->strict(false)
                        ->filterable()
                        ->clickClose()
                        ->expandedKeys(true)
                        ->required()
                        ->data(SystemGroupService::tree([], true))
                        ->addPluginOption('prop', [
                            'value' => 'id',
                        ]),
                ])
                ->setCloseBtn()
                ->setSubmitBtn()
                ->setSubmittedCalls([
                    'parent' => ['admin_index'],
                ])
                ->setAutoClose(true)
                ->render();
        }
    }

    /**
     * 编辑
     * @param int $id 管理员ID
     * @return string
     * @throws \Throwable
     * @throws \yii\base\InvalidConfigException
     */
    public function actionUpdate($id)
    {
        $user = Admin::findIdentity($id);
        if ($this->isPost) {
            if (empty($user)) {
                return $this->asFail("ID:【{$id}】错误,数据不存在!");
            }

            $bodyParams = $this->filteredPost;
            if (!empty($bodyParams['photo'])) {
                $bodyParams['photo'] = App::getFileLinkFromParams($bodyParams, 'photo');
            } else {
                $bodyParams['photo'] = '';
            }
            if ($user->group == Admin::ADMIN_GROUP) {
                unset($bodyParams['group']);
                unset($bodyParams['status']);
                unset($bodyParams['deny_end_time']);
            }
            if (!empty($bodyParams['status']) && !empty($bodyParams['deny_end_time'])) {
                $bodyParams['deny_end_time'] = null;
            }

            $user->setScenario('user_update');
            $user->load($bodyParams);
            if (!$user->validate()) {
                return $this->asFail($user->error);
            }
            if (!empty($bodyParams['password_hash'])) {
                if (empty($bodyParams['password_hash_repeat'])) {
                    return $this->asFail('请重复输入密码');
                }
                if (strcmp($bodyParams['password_hash'], $bodyParams['password_hash_repeat'])) {
                    return $this->asFail('两次输入的密码不一样');
                }

                $user->setPassword($bodyParams['password_hash']);
            }

            $user->save(false);
            return $this->asOk("管理员账号【{$user->username}】编辑成功");

        } else {
            if (empty($user)) {
                return $this->renderContentX(H5::alert('ID错误,数据不存在', 'error'));
            }

            $formControl = [
                'photo' => $this->formControl->file()->label('头像')->max(1)->scenarioImage()->defaultValue($user->photo),
                'username' => $this->formControl->text()->label('账号')->required()->placeholder('请填写账号')->defaultValue($user->username),
                'password_hash' => $this->formControl->password()->label('密码')->placeholder('请填写密码'),
                'password_hash_repeat' => $this->formControl->password()->label('确认密码')->placeholder('请重复密码'),
                'email' => $this->formControl->text()->label('邮箱')->placeholder('请填写邮箱')->defaultValue($user->email),
                'mobile' => $this->formControl->number()->label('手机号')->placeholder('请填写手机号')->defaultValue($user->mobile),
                'status' => $this->formControl->select()->label('状态')->placeholder('请选择')->defaultValue($user->status)->options(['封停/锁定', '正常'])->uiConfig('minimumResultsForSearch', -1),
                'trigger' => $this->formControl->trigger()->when('default', 'status', '==', 0)->triggerItems([
                    'deny_end_time' => $this->formControl->datetime()->label('锁定时间')->placeholder('请选择')->defaultValue($user->deny_end_time),
                ])->display(),
                'group' => $this->formControl->xselectTree()
                    ->label('管理组')
                    ->tips('请选择')
                    ->radio()
                    ->strict(false)
                    ->filterable()
                    ->clickClose()
                    ->expandedKeys(true)
                    ->required()
                    ->defaultValue($user->group)
                    ->data(SystemGroupService::tree([], true))
                    ->addPluginOption('prop', [
                        'value' => 'id',
                    ]),
            ];
            if ($user->group == Admin::ADMIN_GROUP) {
                unset($formControl['group']);
                unset($formControl['status']);
                unset($formControl['trigger']);
            }

            return FormBuilder::instance()
                ->setPartial()
                ->setTitle('编辑')
                ->setRequiredStyle()
                ->setFormControl($formControl)
                ->setCloseBtn()
                ->setSubmitBtn()
                ->setSubmittedCalls([
                    'parent' => ['admin_index'],
                ])
                ->setAutoClose(true)
                ->render();
        }
    }

    /**
     * 删除
     * @return string
     * @throws \Throwable
     * @throws \yii\db\StaleObjectException
     */
    public function actionDelete()
    {
        $id = $this->post['id'];
        $user = Admin::findIdentity($id);
        if (empty($user)) {
            return $this->asFail("ID:【{$id}】错误, 数据不存在");
        }
        if ($user->group == Admin::ADMIN_GROUP) {
            return $this->asFail('系统账号禁止删除');
        }

        $user->delete();
        return $this->asOk("删除管理员账号【{$user->username}】成功");
    }

    /**
     * 查看管理员详情
     * @param int $id 管理员ID
     * @return string
     * @throws \Throwable
     */
    public function actionDetail($id)
    {
        $viewBuilder = $this->viewBuilder;
        $viewBuilder->setPartial();

        $user = Admin::findIdentity($id);
        if (empty($user)) {
            return 'ID错误,数据不存在';
        }
        $groupColumns = SystemGroup::query(['name'])->indexBy('id')->column();
        $groupColumns[Admin::ADMIN_GROUP] = '<i class="bi bi-people-fill f14 pr-1"></i>拥有者';

        $viewBuilder->lists->setTitle('详情')
            ->setListRows([
                '头像' => $this->listRows->item(H5::imgX($user->photo) ?: '-')
                    ->thAttribute(['rowspan' => 4, 'width' => 120])
                    ->tdAttribute(['rowspan' => 4, 'width' => 80]),

                '账号' => $this->listRows->item($user->username)->thAttribute(['width' => 120]),
                '邮箱' => $this->listRows->item($user->email ?: '-')->thAttribute(['width' => 120]),
                '手机号' => $this->listRows->item($user->mobile ?: '-')->thAttribute(['width' => 120]),

                '状态' => $this->listRows->item(H5::badge($user->status ? '正常' : '封停', $user->status ? 'primary' : 'red'))->tdAttribute(['colspan' => 3]),
                '封停截止时间' => $this->listRows->item($user->deny_end_time ?: '-')->tdAttribute(['colspan' => 3]),
                '管理组' => $this->listRows->item($groupColumns[$user->group])->tdAttribute(['colspan' => 3]),
                '邀请码' => $this->listRows->item($user->invite_code ?: '-')->tdAttribute(['colspan' => 3]),
                '谷歌MFA秘钥' => $this->listRows->item($user->google_key ?: '-')->tdAttribute(['colspan' => 3]),
                '单点校验串' => $this->listRows->item($user->sso_key ?: '-')->tdAttribute(['colspan' => 3]),
                '访问令牌' => $this->listRows->item($user->access_token ?: '-')->tdAttribute(['colspan' => 3]),
                '注册时间' => $this->listRows->item($user->created_at)->tdAttribute(['colspan' => 3]),
                '上次更新时间' => $this->listRows->item($user->updated_at)->tdAttribute(['colspan' => 3]),
            ]);

        return $viewBuilder->render();
    }
}